<?php
/**
 * QQ Oauth2.0 授权登录处理
 * date 2019-07-26
 */
namespace oauth;

class qq
{
    private $app_id     = '';                               // QQ应用的 App ID
    private $app_key    = '';                               // QQ应用的 App Key
    private $oauth2_url = 'https://graph.qq.com/oauth2.0';  // QQ OAuth2.0接口URL地址
    private $api2_url   = 'https://graph.qq.com';

    /**
     * 设置Key 和 Secret，如果为空，默认读取config/oauth.php文件里的 qq_app_id和qq_app_key
     *
     * @param array $config 微博应用的Key和Secret值
     */
    public function __construct($config = [])
    {
        $this->app_id  = !empty($config['app_id']) ? $config['app_id'] : config('oauth.qq_app_id');
        $this->app_key = !empty($config['app_key']) ? $config['app_key'] : config('oauth.qq_app_key');
    }

    /**
     * 微博授权跳转URL
     * @param  string $redirect_uri 授权回调地址
     * @param  string $state        回调带回参数，防止CSRF攻击
     * @return mixed
     */
    public function authorize($redirect_uri = '', $state = '')
    {
        if (empty($redirect_uri)) return false;

        $url = $this->oauth2_url . '/authorize?client_id=' . $this->app_id . '&redirect_uri=' . $redirect_uri;
        $url = $url . '&response_type=code&state=' . $state;
        header('location: ' . $url);
    }

    /**
     * 获取微博access_token值
     * @param  string $redirect_uri 授权回调地址
     * @param  string $code         通过authorize获取的code值
     * @return mixed
     */
    public function getAccessToken($redirect_uri = '', $code = '')
    {
        if (empty($redirect_uri) || empty($code)) return false;

        $url = $this->oauth2_url . '/token?grant_type=authorization_code&client_id=' . $this->app_id;
        $url = $url . '&client_secret=' . $this->app_key . '&redirect_uri=' . $redirect_uri . '&code=' . $code;
        
        $res_str = \util\Curl::curlGetRequest($url);

        if (strpos($res_str, "callback") !== false) {
            $lpos    = strpos($res_str, "(");
            $rpos    = strrpos($res_str, ")");
            $res_str = substr($res_str, $lpos + 1, $rpos - $lpos -1);
            $res_arr = json_decode($res_str, true);

            $res_arr['error_code'] = isset($res_arr['error']) ? $res_arr['error'] : '';
            $res_arr['error']      = isset($res_arr['error_description']) ? $res_arr['error_description'] : '';
            $res_json              = json_encode($res_arr);
        } else {
            $params = array();
            parse_str($res_str, $params);   // 把传回来的数据参数变量化
            // 通过access_token获取用户的openID
            $ret_json = $this->_getOpenId($params['access_token']);
            $ret_data = json_decode($ret_json, true);
            if (!empty($ret_data['error'])) {
                $params               = [];
                $params['error_code'] = $ret_data['error'];
                $params['error']      = $ret_data['error_description'];
            } else {
                $params['openid'] = $ret_data['openid'];
            }
            $res_json = json_encode($params);
        }

        // 整理返回数据
        $res_data = [
            'app_account' => ['app_key' => $this->app_id, 'app_secret' => $this->app_key],
            'res_json'    => $res_json
        ];

        return $res_data;
    }

    /**
     * 获取openID
     * @param  string $access_token token值
     * @return json|void|array
     */
    private function _getOpenId($access_token = '')
    {
        $url     = $this->oauth2_url . '/me?access_token=' . $access_token;
        $res_str = \util\Curl::curlGetRequest($url);

        if (strpos($res_str, "callback") !== false) {
            $lpos    = strpos($res_str, "(");
            $rpos    = strrpos($res_str, ")");
            $res_str = substr($res_str, $lpos + 1, $rpos - $lpos -1);
        }

        return $res_str;
    }

    /**
     * 根据access_token和用户id获取用户信息
     * @param  string $access_token token值
     * @param  string $openid       QQ用户openID
     * @return array|void
     */
    public function getUserInfo($access_token = '', $openid = '')
    {
        if (!$access_token || !$openid) return false;
        
        $url = $this->api2_url . '/user/get_user_info?access_token=' . $access_token . '&openid=' . $openid . '&oauth_consumer_key=' . $this->app_id;
        $res = \util\Curl::curlGetRequest($url);

        return $res;
    }

}

